<?php

namespace app\api\service;

use app\api\model\WorkCategoryModel;
use app\api\model\WorkLibraryModel;
use app\api\model\WorkTypeModel;
use bgb\office\excel\Excel;
use MongoDB\Driver\Exception\LogicException;
use PhpOffice\PhpSpreadsheet\IOFactory;
use think\Config;
use think\Db;
use think\Exception;
use think\Request;
use think\Validate;

class WorkService extends Api
{
    protected static $instance;

    public function __construct(Request $request = null)
    {
        parent::__construct($request);
    }

    public static function getInstance()
    {
        if (is_null(self::$instance))
        {
            self::$instance = new static();
        }
        return self::$instance;
    }

    /**
     * 添加、编辑工种库
     */
    public function changeWorkLibrary($params)
    {
        $Validate = new Validate([
            'company_id' => 'require',
            'title' => 'require',
            'status' => 'require',
        ],[
            'company_id' => '所属保司必选',
            'title' => '工种库名称必填',
            'status' => '工种库状态必填',
        ]);
        if (!$Validate->check($params))
        {
            $this->error($Validate->getError());
        }
        Db::startTrans();
        try{
            $saveData = [
                'company_id' => $params['company_id'],
                'title' => $params['title'],
                'status' => $params['status']
            ];
            if (!empty($params['id']))
            {
                $saveData['u_time'] = datetime(time(), 'Y-m-d H:i:s');
                $res = WorkLibraryModel::getInstance()->update($params['id'], $saveData);
            }else{
                $saveData['c_time'] = datetime(time(), 'Y-m-d H:i:s');
                $res = WorkLibraryModel::getInstance()->insert($saveData);
            }

            LogService::getInstance()->writeSysLog([
                'operation' => '/api/work/changeWorkLibrary',
                'title' => !empty($params['id']) ? '编辑' : '添加',
                'content' => $params,
            ]);

            Db::commit();
            return $res;
        }catch (Exception $e)
        {
            Db::rollback();
            $this->error($e->getMessage());
        }
    }

    /**
     * 获取工种库信息
     */
    public function getWorkLibrary($params)
    {
        $Validate = new Validate([
            'id' => 'require',
        ],[
            'id' => '缺少工种库唯一标识'
        ]);
        if (!$Validate->check($params))
        {
            $this->error($Validate->getError());
        }
        $info = WorkLibraryModel::getInstance()->find($params['id']);
        return $info;
    }

    /**
     * 获取工种库列表
     */
    public function getWorkLibraryList($params)
    {
        $page = $this->request->param('page', 1);
        $limit = $this->request->param('limit', 15);
        $start = ($page - 1) * $limit;

        $where = [];

        if (!empty($params['company_id']))
        {
            $where['company_id'] = ['eq', $params['company_id']];
        }
        if (!empty($params['title']))
        {
            $where['title'] = ['LIKE', '%'.$params['title'].'%'];
        }
        if (isset($params['status']))
        {
            $where['status'] = ['eq', $params['status']];
        }

        $total = WorkLibraryModel::getInstance()->count($where);
        $list = WorkLibraryModel::getInstance()->select($where, '*', $start, $limit);

        $company = CompanyService::getInstance()->getCompany([]);
        foreach ($list as $k => $v)
        {
            foreach ($company as $kk => $vv)
            {
                if ($vv['id'] == $v['company_id'])
                {
                    $list[$k]['company_name'] = $vv['name'];
                }
            }
        }
        return [
            'total' => $total,
            'list' => $list
        ];
    }

    /**
     * 获取工种库 - 下拉框使用
     */
    public function getWorkLibrarySelect($params)
    {
        $Validate = new Validate([
            'company_id' => 'require',
        ], [
            'company_id' => '保司标识必填'
        ]);
        if (!$Validate->check($params))
        {
            $this->error($Validate->getError());
        }
        $list = WorkLibraryModel::getInstance()->select([
            'company_id' => ['eq', $params['company_id']],
            'status' => ['eq', 1]
        ], 'id, title');
        return $list;
    }

    /**
     * 添加、编辑工种类别
     */
    public function changeWorkCategory($params)
    {
        $Validate = new Validate([
            'company_id' => 'require',
            'lib_id' => 'require',
            'title' => 'require',
            'status' => 'require',
        ], [
            'company_id' => '所属保司必填',
            'lib_id' => '所属工种库必填',
            'title' => '职业类别名称必填',
            'status' => '职业类别状态必填',
        ]);
        if (!$Validate->check($params))
        {
            $this->error($Validate->getError());
        }
        Db::startTrans();
        try{
            $saveData = [
                'company_id' => $params['company_id'],
                'lib_id' => $params['lib_id'],
                'title' => $params['title'],
                'status' => $params['status'],
            ];
            if (!empty($params['id']))
            {
                $saveData['u_time'] = datetime(time(), 'Y-m-d H:i:s');
                $res = WorkCategoryModel::getInstance()->update($params['id'], $saveData);
            }else{
                $saveData['c_time'] = datetime(time(), 'Y-m-d H:i:s');
                $res = WorkCategoryModel::getInstance()->insert($saveData);
            }
            LogService::getInstance()->writeSysLog([
                'operation' => 'api/work/changeWorkCategory',
                'title' => !empty($params['id']) ? '编辑' : '添加',
                'content' => $params,
            ]);
            Db::commit();
            return $res;
        }catch (Exception $e)
        {
            Db::rollback();
            $this->error($e->getMessage());
        }
    }

    /**
     * 获取职业类别列表
     */
    public function getWorkCategoryList($params)
    {
        $Validate = new Validate([
            'lib_id' => 'require',
        ],[
            'lib_id' => '缺少工种库唯一标识'
        ]);
        if (!$Validate->check($params))
        {
            $this->error($Validate->getError());
        }
        $page = $this->request->param('page', 1);
        $limit = $this->request->param('limit', 15);
        $start = ($page - 1) * $limit;

        $where = [
            'lib_id' => ['eq', $params['lib_id']]
        ];
        $total = WorkCategoryModel::getInstance()->count($where);
        $list = WorkCategoryModel::getInstance()->select($where);
        return [
            'work_library' => WorkLibraryModel::getInstance()->value([
                'id' => ['eq', $params['lib_id']]
            ]),
            'total' => $total,
            'list' => $list
        ];
    }

    /**
     * 获取职业类别 - 下拉框使用
     */
    public function getWorkCateSelect($params)
    {
        $Validate = new Validate([
//            'company_id' => 'require',
            'lib_id' => 'require'
        ], [
//            'company_id' => '保司标识无效',
            'lib_id' => '工种库标识无效'
        ]);
        if (!$Validate->check($params))
        {
            $this->error($Validate->getError());
        }
        $list = WorkCategoryModel::getInstance()->select([
//            'company_id' => ['eq', $params['company_id']],
            'lib_id' => ['eq', $params['lib_id']]
        ], 'id, title');
        return $list;
    }

    /**
     * 获取职业类别信息
     */
    public function getWorkCategoryInfo($params)
    {
        $Validate = new Validate([
            'id' => 'require'
        ], [
            'id' => '缺少职业类别识别标识'
        ]);
        if (!$Validate->check($params))
        {
            $this->error($Validate->getError());
        }
        $info = WorkCategoryModel::getInstance()->find($params['id']);
        return $info;
    }

    /**
     * 添加、编辑工种
     */
    public function changeWorkType($params)
    {
        $Validate = new Validate([
            'company_id' => 'require',
            'cate_id' => 'require',
            'title' => 'require',
//            'code' => 'require',
            'pid' => 'require',
            'level' => 'require',
        ], [
            'company_id' => '所属保司必填',
            'cate_id' => '职业类别必填',
            'title' => '工种名称必填',
//            'code' => '工种编码必填',
            'pid' => '所属分类必填',
            'level' => '工种等级必填',
        ]);
        if (!$Validate->check($params))
        {
            $this->error($Validate->getError());
        }
        if ($params['level'] == 4)
        {
            $Validate = new Validate([
                'status' => 'require',
                'grade' => 'require',
                'is_high' => 'require',
                'is_insure_before_check' => 'require',
            ], [
                'status' => '工种状态必填',
                'grade' => '工种类别必填',
                'is_high' => '是否包含高空必填',
                'is_insure_before_check' => '是否保前审核必填',
            ]);
            if (!$Validate->check($params))
            {
                $this->error($Validate->getError());
            }
        }

        Db::startTrans();
        try{
            $saveData = [
                'company_id' => $params['company_id'],
                'cate_id' => $params['cate_id'],
                'title' => $params['title'],
                'code' => isset($params['code']) ? $params['code'] : '',
                'pid' => $params['pid'],
                'level' => $params['level'],
                'status' => isset($params['status']) ? $params['status'] : 1,
                'grade' => isset($params['grade']) ? $params['grade'] : 5,
                'is_high' => isset($params['is_high']) ? $params['is_high'] : 0,
                'is_insure_before_check' => !empty($params['is_insure_before_check']) ? $params['is_insure_before_check'] : 0,
            ];
            if (!empty($params['id']))//大分类id
            {
                $saveData['u_time'] = datetime(time(), 'Y-m-d H:i:s');
                $res = WorkTypeModel::getInstance()->update($params['id'], $saveData);
            }else{
                $saveData['c_time'] = datetime(time(), 'Y-m-d H:i:s');
                $res = WorkTypeModel::getInstance()->insert($saveData);
            }

            LogService::getInstance()->writeSysLog([
                'operation' => 'api/work/changeWorkType',
                'title' => !empty($params['id']) ? '编辑' : '添加',
                'content' => $params,
            ]);

            Db::commit();
            return $res;
        }catch (Exception $e)
        {
            Db::rollback();
            $this->error($e->getMessage());
        }
    }

    /**
     * 获取工种信息
     */
    public function getWorkTypeInfo($params)
    {
        $Validate = new Validate([
            'id' => 'require',
            'level' => 'require',
        ], [
            'id' => '工种标识无效',
            'level' => '工种类别必填'
        ]);
        if (!$Validate->check($params))
        {
            $this->error($Validate->getError());
        }
        $field = $params['level'] == 4 ? '*' : 'company_id,cate_id,title,code,pid,level';
        $info = WorkTypeModel::getInstance()->find($params['id'], $field);
        $pid = self::getParent($params['id']);
        $info['pidArr'] = $pid;
        return $info;
    }

    /**
     * 获取工种父级分类
     */
    public function getParent($id, $data = [])
    {
        $pid = WorkTypeModel::getInstance()->value([
            'id' => ['eq', $id]
        ], 'pid');
        if ($pid == 0)
        {
            $result = [];
            krsort($data);
            foreach ($data as $item)
            {
                $result[] = $item;
            }
            return $result;
        }else{
            $data[] = $pid;
            return self::getParent($pid, $data);
        }
    }

    /**
     * 获取工种列表
     */
    public function getWorkTypeList($params)
    {
        $Validate = new Validate([
            'cate_id' => 'require'
        ], [
            'cate_id' => '职业类别标识无效'
        ]);
        if (!$Validate->check($params))
        {
            $this->error($Validate->getError());
        }
        $where = [
            'cate_id' => ['eq', $params['cate_id']]
        ];
        if (isset($params['level']))
        {
            $where['level'] = ['elt', $params['level']];
        }
        $list = WorkTypeModel::getInstance()->select($where);
        $tIds = array_column($list, 'id');
        $allWorkType = WorkTypeModel::getInstance()->select([], 'id,title,pid');
        $ids = MenuService::getInstance()->getParentIds($allWorkType, $tIds, true);
        $list = WorkTypeModel::getInstance()->select([
            'id' => ['in', array_merge($ids, $tIds)]
        ]);
        $treeData = MenuService::getInstance()->getMenuTree($list, 0, 1);
        return $treeData;
    }

    /**
     * 批量更新保前审核、批量更新状态
     */
    public function changeAllWorkType($params)
    {
        $Validate = new Validate([
            'cate_id' => 'require',
        ], [
            'cate_id' => '职业类别标识无效'
        ]);
        if (!$Validate->check($params)) {
            $this->error($Validate->getError());
        }
        $saveData = [];
        if (isset($params['beforeCheck']))
        {
            $saveData['is_insure_before_check'] = $params['beforeCheck'];
        }
        if (isset($params['status']))
        {
            $saveData['status'] = $params['status'];
        }
        if (empty($saveData))
        {
            $this->error('数据无效，无可更新数据');
        }
        return Db::name('work_type')->where([
            'cate_id' => ['eq', $params['cate_id']]
        ])->update($saveData);
    }

    /**
     * 批量上传工种
     */
    public function uploadWorkType($params)
    {
        $Validate = new Validate([
            'lib_id' => 'require',
            'company_id' => 'require',
        ], [
            'lib_id' => '工种库标识无效',
            'company_id' => '所属保司标识必填'
        ]);
        if (!$Validate->check($params))
        {
            $this->error($Validate->getError());
        }
        $data = UploadService::getInstance()->upload();
        if ($data['status'])
        {
            $domain = Config::get('domain.'.Domain);
            $fileUrl = str_replace($domain['domain'], '', $data['returnData']['fileUrl']);
            $excel = new Excel();
            $fileData = $excel->reader('.'.$fileUrl);
            unset($fileData[0]);

            Db::startTrans();
            try{
                $workCategory = WorkCategoryModel::getInstance()->column([
                    'lib_id' => ['eq', $params['lib_id']],
                    'company_id' => ['eq', $params['company_id']]
                ], 'id', 'title');//职业类别  识别file数据是否存在该类别

//                LogService::getInstance()->writeSysLog([
//                    'operation' => 'api/work/uploadWorkType',
//                    'title' => '批量上传工种',
//                    'content' => $fileData,
//                ]);
                LogService::getInstance()->writeLogInfo($fileData);

                //组建分类数据
                foreach ($fileData as $k => $v)
                {
                    //查找职业类别标识
                    $cateId = isset($workCategory[intval($v[5]).'类']) ? $workCategory[intval($v[5]).'类'] : WorkCategoryModel::getInstance()->insert([
                        'company_id' => $params['company_id'],
                        'lib_id' => $params['lib_id'],
                        'title' => intval($v[5]).'类',
                        'status' => 1,
                        'c_time' => datetime(time(), 'Y-m-d H:i:s')
                    ]);
                    $workCategory[intval($v[5]).'类'] = $cateId;

                    if (!empty($v[4]))
                    {
                        if (!empty($v[0]))
                        {
                            $dcode = preg_match('/\d+/', $v[0],$arr) ? $arr[0] : datetime(time(), 'md').rand(1000, 9999);
                            $dtitle = str_replace($dcode, '', $v[0]);
                            $dDataNum[] = $dcode;
                            $dData[] = [
                                'company_id' => $params['company_id'],
                                'cate_id' => $cateId,
                                'title' => $dtitle,
                                'code' => $dcode,
                                'pid' => 0,
                                'level' => 1,
                                'status' => 1,
                                'grade' => intval($v[5]),
                                'is_high' => intval($v[7]),
                                'is_insure_before_check' => intval($v[8]),
                            ];
                        }
                        if (!empty($v[1]))
                        {
                            $zcode = preg_match('/\d+/', $v[1],$arr) ? $arr[0] : $dcode.rand(1000,9999);
                            $ztitle = str_replace($zcode, '', $v[1]);
                            $zDataNum[] = $zcode;
                            $zData[] = [
                                'company_id' => $params['company_id'],
                                'cate_id' => $cateId,
                                'title' => $ztitle,
                                'code' => $zcode,
                                'pid' => 0,
                                'level' => 2,
                                'status' => 1,
                                'grade' => intval($v[5]),
                                'is_high' => intval($v[7]),
                                'is_insure_before_check' => intval($v[8]),
                                'dCode' => $dcode,
                            ];
                        }
                        if (!empty($v[2]))
                        {
                            $xcode = preg_match('/\d+/', $v[2],$arr) ? $arr[0] : $zcode.rand(1000, 9999);
                            $xtitle = str_replace($xcode, '', $v[2]);
                            $xDataNum[] = $xcode;
                            $xData[] = [
                                'company_id' => $params['company_id'],
                                'cate_id' => $cateId,
                                'title' => $xtitle,
                                'code' => $xcode,
                                'pid' => 0,
                                'level' => 3,
                                'status' => 1,
                                'grade' => intval($v[5]),
                                'is_high' => intval($v[7]),
                                'is_insure_before_check' => intval($v[8]),
                                'zCode' => $zcode,
                            ];
                        }
                        $xfCode = empty($v[3]) ? (preg_match('/\d+/', $v[2],$arr) ? $arr[0] : $xcode.rand(1000, 9999)) : $v[3];
                        $xfTitle = str_replace($xfCode, '', $v[4]);
                        $xfDataNum[] = $xfCode;
                        $xfData[] = [
                            'company_id' => $params['company_id'],
                            'cate_id' => $cateId,
                            'title' => $xfTitle,
                            'code' => $xfCode,
                            'pid' => 0,
                            'level' => 4,
                            'status' => empty($v[6]) ? 1 : intval($v[6]),
                            'grade' => intval($v[5]),
                            'is_high' => intval($v[7]),
                            'is_insure_before_check' => intval($v[8]),
                            'xCode' => $xcode
                        ];
                    }
                }
                //插入大分类
                WorkTypeModel::getInstance()->delete([
                    'code' => ['in', $dDataNum],
                    'cate_id' => ['eq', $cateId]
                ]);
                WorkTypeModel::getInstance()->insertAll($dData);
                $dDataList = WorkTypeModel::getInstance()->column([
                    'code' => ['in', $dDataNum]
                ], 'id', 'code');

                //插入中分类
                WorkTypeModel::getInstance()->delete([
                    'code' => ['in', $zDataNum],
                    'cate_id' => ['eq', $cateId]
                ]);
                foreach($zData as $k => &$v)
                {
                    $v['pid'] = $dDataList[$v['dCode']];
                    unset($v['dCode']);
                }
                WorkTypeModel::getInstance()->insertAll($zData);
                $zDataList = WorkTypeModel::getInstance()->column([
                    'code' => ['in', $zDataNum]
                ], 'id', 'code');

                //插入小分类
                WorkTypeModel::getInstance()->delete([
                    'code' => ['in', $xDataNum],
                    'cate_id' => ['eq', $cateId]
                ]);
                foreach ($xData as $k => &$v)
                {
                    $v['pid'] = $zDataList[$v['zCode']];
                    unset($v['zCode']);
                }
                WorkTypeModel::getInstance()->insertAll($xData);
                $xDataList = WorkTypeModel::getInstance()->column([
                    'code' => ['in', $xDataNum]
                ], 'id', 'code');

                //插入细分分类
                WorkTypeModel::getInstance()->delete([
                    'code' => ['in', $xfDataNum],
                    'cate_id' => ['eq', $cateId]
                ]);
                foreach ($xfData as $k => &$v)
                {
                    $v['pid'] = $xDataList[$v['xCode']];
                    unset($v['xCode']);
                }
                WorkTypeModel::getInstance()->insertAll($xfData);
                Db::commit();
                return true;
            }catch (Exception $e)
            {
                Db::rollback();
                $this->error($e->getMessage());
            }

        }else{
            $this->error('文件处理失败，请重试');
        }
    }
}